package cn.com.cfae.iras.doc.analyze.components.integrity;

import cn.com.cfae.iras.doc.analyze.beans.web.ContentAndPosition;
import cn.com.cfae.iras.doc.analyze.beans.web.Detail;
import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.components.common.Constants;
import cn.com.cfae.iras.doc.analyze.parse.SimilarAnalyser;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.model.ChapterModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractBizModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractItem;
import cn.com.cfae.iras.doc.analyze.parse.model.PageModel;
import cn.com.cfae.iras.doc.analyze.parse.model.SectionModel;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 佟媛媛 on 18/10/23.
 * 检查关键句是否存在 完整性
 */

@Component("I1030")
@Scope("prototype")
public class I1030 extends BaseComponent {

    private static Logger log = LoggerFactory.getLogger(I1030.class);

    private String keyword;//关键字

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    private String chapterId;//章节

    public String getChapterId() {
        return chapterId;
    }

    public void setChapterId(String chapterId) {
        this.chapterId = chapterId;
    }


    @Override
    public List<ComponentResult> handlerM() {
        return null;
    }

    public Map _handlerM(){
        return ifKeywordExist2(getCatalogId());
    }
    public Map _handlerBM(){
        String catalogId = getCatalogId();
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(getCatalogId())){
            if(getCatalogId().split("-").length>1){
                catalogId = "BM-"+getCatalogId().split("-")[1];
            }else if(getCatalogId().split("-").length==1){
                catalogId = "BM";
            }
        }
        setCatalogId(catalogId);
        return _handlerM();
    }
    public Map _handlerDM(){
        String catalogId = getCatalogId();
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(getCatalogId())){
            if(getCatalogId().split("-").length>1){
                catalogId = "DM-"+getCatalogId().split("-")[1];
            }else if(getCatalogId().split("-").length==1){
                catalogId = "DM";
            }
        }
        setCatalogId(catalogId);
        return _handlerM();
    }
    public Map _handlerBDM(){
        String catalogId = getCatalogId();
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(getCatalogId())){
            if(getCatalogId().split("-").length>1){
                catalogId = "BDM-"+getCatalogId().split("-")[1];
            }else if(getCatalogId().split("-").length==1){
                catalogId = "BDM";
            }
        }
        setCatalogId(catalogId);
        return _handlerM();
    }


    /**
     * @auth 佟媛媛
     * @date 18/10/26 下午2:54
     * @desc 跨行判断关键字是否存在且返回文本和坐标
     */
    public Map ifKeywordExist2(String catalogId){
        ChapterModel chapterModel = getChapterModel(catalogId);
        int pageNum = chapterModel.getStartPage();
        Map rs = ifInContent(chapterModel,pageNum);
        return rs;
    }


    /**
     * @auth 佟媛媛
     * @date 18/12/3 下午8:01
     * @desc 在章节中判断
     */
    private Map ifInContent(ChapterModel chapterModel,int pageNum){
        Map rs = new HashMap();
        List<ContentAndPosition> contentAndPositionList = new ArrayList<ContentAndPosition>();
        List<PageModel> pageModelList = chapterModel!=null?chapterModel.getPageModelList():null;
        if(!CollectionUtils.isEmpty(pageModelList)){
            boolean boo = false;
            for(PageModel pageModel : pageModelList){
                if(boo){
                    break;
                }
                JsonArray jsonTextDataArray = pageModel.getJsonTextData()!=null?pageModel.getJsonTextData().getAsJsonArray():null;
                if(jsonTextDataArray!=null){
                    for(JsonElement element : jsonTextDataArray){
                        if(boo){
                            break;
                        }
                        JsonArray data = element.getAsJsonObject()!=null?element.getAsJsonObject().getAsJsonArray("data"):null;//当页文本
                        if(data!=null && data.size()>1){
                            List<ContentAndPosition> __contentAndPositionList = handleText(data,pageModel);
                            contentAndPositionList.addAll(__contentAndPositionList);
                            if(__contentAndPositionList.size()>0)  boo = true;
                        }
                    }
                }
            }
        }
        rs.put("contentAndPositionList",contentAndPositionList);
        rs.put("exist",contentAndPositionList.size()==0?false:true);
        rs.put("pageNum",pageNum);
        return rs;
    }


    /**
     * @auth 佟媛媛
     * @date 18/11/23 下午5:28
     * @desc 数据库关键字及同义词以|分割
     */
    private Map ifContain(JsonObject line1,JsonObject line2,JsonObject line3,int index1,int index2,int index3){
        Map map = new HashMap();
        StringBuilder text12 = new StringBuilder();
        StringBuilder text23 = new StringBuilder();
        StringBuilder text123 = new StringBuilder();
        text12.append(line1.get("text").getAsString()).append(line2.get("text").getAsString());
        text23.append(line2.get("text").getAsString()).append(line3.get("text").getAsString());
        text123.append(line1.get("text").getAsString()).append(line2.get("text").getAsString()).append(line3.get("text").getAsString());
        String[] keywords = getKeyword().split("\\|");
        map.put("exist",false);
        map.put("text",keywords[0]);
        map.put("similar",0.0);
        map.put("index","");
        if(StringUtils.isEmpty(text12) && StringUtils.isEmpty(text23) && StringUtils.isEmpty(text123)){
            return map;
        }
        for(String keyword : keywords){
            double d = 0;
            double d1 = SimilarAnalyser.getInstance().similarity(keyword,text12.toString());
            double d2 = SimilarAnalyser.getInstance().similarity(keyword,text23.toString());
            double d3 = SimilarAnalyser.getInstance().similarity(keyword,text123.toString());
            if(d1 > Constants.SEEM_MAX || d2 > Constants.SEEM_MAX || d3 > Constants.SEEM_MAX){
                double[] doubles = new double[]{d1,d2,d3};
                for(double _d : doubles){
                    if(_d > d) d = _d;
                }
                if(d==d1 && text12.length()>=keyword.length()){
                    map.put("exist",true);
                    map.put("text",keyword);
                    map.put("similar",d3);
                    map.put("index",new StringBuilder().append(index1).append("@").append(index2).toString());
                    break;
                }else if(d==d2 && text23.length()>=keyword.length()){
                    map.put("exist",true);
                    map.put("text",keyword);
                    map.put("similar",d3);
                    map.put("index",new StringBuilder().append(index2).append("@").append(index3).toString());
                    break;
                }else if(d==d3){
                    map.put("exist",true);
                    map.put("text",keyword);
                    map.put("similar",d3);
                    map.put("index",new StringBuilder().append(index1).append("@").append(index2).append("@").append(index3).toString());
                    break;
                }else {
                    map.put("exist",true);
                    map.put("text",keyword);
                    map.put("similar",d3);
                    map.put("index",new StringBuilder().append(index1).append("@").append(index2).append("@").append(index3).toString());
                    break;
                }
            }
        }
        return map;
    }


    /**
     * @auth 佟媛媛
     * @date 18/11/28 下午5:02
     * @desc 检查到第一个即返回
     */
    private List<ContentAndPosition> handleText(JsonArray data,PageModel pageModel){
        List<ContentAndPosition> _contentAndPositionList = new ArrayList<ContentAndPosition>();
        int pageNum = pageModel.getPageNumber();
        Map<String,Double> maps = new HashMap();
        for(int i=0;i<data.size()-3;i++){
            JsonObject line1 = returnOne(data.get(i).getAsJsonArray());
            JsonObject line2 = returnOne(data.get(i+1).getAsJsonArray());
            JsonObject line3 = returnOne(data.get(i+2).getAsJsonArray());
            Map map = ifContain(line1,line2,line3,i,i+1,i+2);
            boolean pp = (boolean)map.get("exist");
            String content = (String)map.get("text");
            double similar = (double)map.get("similar");
            String index = (String) map.get("index");
            if(pp && !StringUtils.isEmpty(index)){
                maps.put(index,similar);
            }
        }
        if(MapUtils.isNotEmpty(maps)){
            String key = null;
            double max = -1;
            for(Map.Entry<String,Double> entry : maps.entrySet()){
                if(entry.getValue()>max){
                    max = entry.getValue();
                    key = entry.getKey();
                }
            }
            if(!StringUtils.isEmpty(key)){
                String[] keys = key.split("@");
                if(keys.length==2){
                    JsonObject line1 = returnOne(data.get(Integer.valueOf(keys[0])).getAsJsonArray());
                    JsonObject line2 = returnOne(data.get(Integer.valueOf(keys[1])).getAsJsonArray());
                    List<ContentAndPosition> contentAndPositionList = line3(line1,line2,null,pageNum);
                    _contentAndPositionList.addAll(contentAndPositionList);
                }else if(keys.length==3){
                    JsonObject line1 = returnOne(data.get(Integer.valueOf(keys[0])).getAsJsonArray());
                    JsonObject line2 = returnOne(data.get(Integer.valueOf(keys[1])).getAsJsonArray());
                    JsonObject line3 = returnOne(data.get(Integer.valueOf(keys[2])).getAsJsonArray());
                    List<ContentAndPosition> contentAndPositionList = line3(line1,line2,line3,pageNum);
                    _contentAndPositionList.addAll(contentAndPositionList);
                }
            }
        }
        return _contentAndPositionList;
    }



    private List<Integer> getSymbolList(String str) {
        List<Integer> list = new ArrayList<>();
        try{
            // 特殊字符
            String regEx="[`~!@#$^&*()=|{}':;',\\[\\]<>/?~！@#￥……&*（）－|{}【】‘；：”“’\"。，、？．]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(str);
            list.add(0);
            int i=0;
            while(m.find()){
                int index = m.start()-i;
                if(!list.contains(index)) list.add(index);
                i++;
            }
            list.add(stringFilter(str).length());
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return list;
    }


    private List<ContentAndPosition> line3(JsonObject line1,JsonObject line2,JsonObject line3,int pageNum){
        List<ContentAndPosition> contentAndPositionList = new ArrayList<>();
        if(line1!=null){
            ContentAndPosition contentAndPosition1 = new ContentAndPosition();
            contentAndPosition1.setContent(line1.get("text").getAsString());
            contentAndPosition1.setX(line1.get("left").getAsDouble());
            contentAndPosition1.setY(line1.get("top").getAsDouble());
            contentAndPosition1.setPageNum(pageNum);
            contentAndPositionList.add(contentAndPosition1);
        }
        if(line2!=null){
            ContentAndPosition contentAndPosition2 = new ContentAndPosition();
            contentAndPosition2.setContent(line2.get("text").getAsString());
            contentAndPosition2.setX(line2.get("left").getAsDouble());
            contentAndPosition2.setY(line2.get("top").getAsDouble());
            contentAndPosition2.setPageNum(pageNum);
            contentAndPositionList.add(contentAndPosition2);
        }
        if(line3!=null){
            ContentAndPosition contentAndPosition3 = new ContentAndPosition();
            contentAndPosition3.setContent(line3.get("text").getAsString());
            contentAndPosition3.setX(line3.get("left").getAsDouble());
            contentAndPosition3.setY(line3.get("top").getAsDouble());
            contentAndPosition3.setPageNum(pageNum);
            contentAndPositionList.add(contentAndPosition3);
        }
        return contentAndPositionList;
    }





    public Map getWebData(List<Map> mapList,String type){
        Map rs = new HashMap();
        Map<String,String> catalogMap = new HashMap();
        List<Detail> disclosedList = new ArrayList<>();
        List<Detail> undisclosedList = new ArrayList<>();
        List<Detail> seemDisclosedList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(mapList)){
            for(Map map : mapList){
                String catalog_id = (String) map.get("catalogId");
                catalogMap.put(catalog_id,catalog_id);
            }
            for(String key : catalogMap.keySet()){
                List<Detail.Result> disclosedResults = new ArrayList<>();
                List<Detail.Result> undisclosedResults = new ArrayList<>();
                for(Map m : mapList){
                    Detail __map = new Detail();
                    String catalog_id = (String) m.get("catalogId");
                    String catalogId = org.apache.commons.lang3.StringUtils.isNotEmpty(catalog_id)&&catalog_id.split("-").length>1?(type+"-"+catalog_id.split("-")[1]):catalog_id;//因为子表在数据库中不区分M，BM，DM，DBM，所以title得需要拼接
                    String chapater_id = (String) m.get("chapterId");
                    String rule_name = (String) m.get("ruleTitle");
                    String _keyword = (org.apache.commons.lang3.StringUtils.isNotEmpty((String)m.get("regulationDetail"))?m.get("regulationDetail").toString().split("\\|")[0]:(String) m.get("regulationDetail"));//数据库中以|分割存储同义词，前端展示时只需显示第一个即可
                    List<ContentAndPosition> contentAndPositionList = (List<ContentAndPosition>)m.get("contentAndPositionList");
                    boolean exist = (boolean)m.get("exist");
                    if(key.equals(catalog_id)){
                        __map.setCatalogId(catalogId);
                        __map.setRuleName(rule_name);
                        Integer pageNum = (Integer) m.get("pageNum");
                        Detail.Result _m = new Detail().new Result();
                        List<Detail.TextPosition> xys = new ArrayList<>();
                        if(!CollectionUtils.isEmpty(contentAndPositionList)){
                            for(ContentAndPosition contentAndPosition : contentAndPositionList){
                                pageNum = contentAndPosition.getPageNum();
                                Detail.TextPosition xy = new Detail().new TextPosition();
                                xy.setX(contentAndPosition.getX());
                                xy.setY(contentAndPosition.getY());
                                xy.setContent(contentAndPosition.getContent());
                                if(!(contentAndPosition.getX()==0 && contentAndPosition.getY()==0)) xys.add(xy);
                            }
                        }
                        _m.setUid(UUID.randomUUID().toString());
                        _m.setKeyword("关键句检查-"+ _keyword);
                        _m.setRegulationId((String)m.get("regulationId"));
                        _m.setTextPosition(xys);
                        _m.setPageNum(pageNum);
                        _m.setChapterId(chapater_id);
                        if(exist){
                            _m.setAnnotationFlag(false);
                            _m.setPromptMessage("正确");
                            disclosedResults.add(_m);
                            __map.setResults(disclosedResults);
                            if(!ifInList(disclosedList,catalog_id)) disclosedList.add(__map);
                        }else{
                            _m.setAnnotationFlag(true);
                            _m.setPromptMessage((String)m.get("promptMessage"));
                            undisclosedResults.add(_m);
                            __map.setResults(undisclosedResults);
                            if(!ifInList(undisclosedList,catalog_id)) undisclosedList.add(__map);
                        }
                    }
                }

            }
        }
        rs.put("disclosed",disclosedList);
        rs.put("undisclosed",undisclosedList);
        rs.put("seem_disclosed",seemDisclosedList);
        return rs;
    }

    private boolean ifInList(List<Detail> list,String value){
        if(CollectionUtils.isEmpty(list)){
            return false;
        }
        for(Detail d : list){
            if(!StringUtils.isEmpty(d.getCatalogId()) && d.getCatalogId().equals(value)){
                return true;
            }
        }
        return false;
    }



    @Override
    public List<ComponentResult> handlerBM() {
        return null;
    }

    @Override
    public List<ComponentResult> handlerDM() {
        return null;
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        return null;
    }
}
